package main

import (
	"encoding/json"
	"geek-cloud-native/httpserver/metrics"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"log"
	"math/rand"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var version = "v1"

//go:generate go env -w GO111MODULE=on
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
//go:generate go mod tidy
//go:generate go mod download

// @title 简单的HTTP服务
// @version v1.0
// @description 实现一个简单的HTTP服务
// @termsOfService https://gitee.com/coolops/geek-cloud-native/chapter04-0925
func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/healthz", HeaderMiddleware(HttpserverHealthCheck))
	mux.HandleFunc("/version", HeaderMiddleware(HttpserverShowVersion))
	mux.HandleFunc("/", metrics.NewMetrics(HttpserverRootHandler))

	s := &http.Server{
		Handler: mux,
		Addr:    ":" + "8080",
	}

	// 启动监控服务
	go func() {
		http.Handle("/metrics", promhttp.Handler())
		if err := http.ListenAndServe(":9527", nil); err != nil {
			log.Printf("metrics port listen failed. err: %s", err)
		}
	}()
	// 启动服务
	go func() {
		if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("s.ListenAndServer err: %v", err)
		}
	}()
	log.Printf("service started ......")
	// 等待中断信号
	quit := make(chan os.Signal)
	// 接收syscall.SIGINT和syscall.SIGTERM信号
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Printf("Shutting down server ......")
}

func HttpserverRootHandler(writer http.ResponseWriter, request *http.Request) {
	log.Printf("start do rootHandler")
	// 随机延迟0-2s
	time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond)

	response := map[string]interface{}{
		"status": http.StatusOK,
		"msg":    "主页面",
	}
	resB, _ := json.Marshal(response)
	_, err := writer.Write(resB)
	if err != nil {
		log.Printf("do routerHandler failed")
	}
	log.Printf("end do rootHandler")
	return
}

func HttpserverShowVersion(writer http.ResponseWriter, request *http.Request) {
	response := map[string]interface{}{
		"status":  http.StatusOK,
		"msg":     "获取系统版本",
		"version": request.Header.Get("version"),
	}
	resB, _ := json.Marshal(response)
	_, err := writer.Write(resB)
	if err != nil {
		log.Printf("get version failed")
	}
	log.Printf("get version success")
	return
}

func HttpserverHealthCheck(writer http.ResponseWriter, request *http.Request) {
	response := map[string]interface{}{
		"status": http.StatusOK,
		"msg":    "监控检测页面",
	}
	resB, _ := json.Marshal(response)
	_, err := writer.Write(resB)
	if err != nil {
		log.Printf("healthz check failed")
	}
	log.Printf("healthz check success")
	return
}

func HeaderMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("token")
		w.Header().Set("token", token)
		w.Header().Set("version", version)
		next(w, r)
	}
}
